/**
 * @class 深空摄像机组件
 * @author DuskyHuang 圣子
 * @description 观察天空盒、星座和深空背景。
 * @description 自动同步主相机位置和方位角。
*/

import { _decorator, Vec3, Component, RenderTexture, Sprite, Camera, sys, Node } from 'cc';
import { core } from 'cfw';
import { interstellar } from 'const';
import { CosmosController } from '../controllers/cosmos-controller';
import { cosmos } from '../proxies/cosmos-proxy';
import { visit } from '../proxies/visit-proxy';
import { SkyboxCube, Blackhole } from 'prefabs';
import { smoothstep } from 'algorithms';
import { GravitationalLens } from './gravitational-lens';
const { ccclass, property } = _decorator;

@ccclass('cocosmos.DeepSkyCamera')
export class DeepSkyCamera extends Component {

    @property(GravitationalLens)
    public gravitational: GravitationalLens = null;

    @property(RenderTexture)
    public deepSkyRT: RenderTexture = null;

    @property(Sprite)
    public skyBackRenderer: Sprite = null;

    @property(Blackhole)
    public blackhole: Blackhole = null;

    @property(SkyboxCube)
    public skybox: SkyboxCube = null;

    @property
    public set useRT(arg: boolean) {
        if (arg === this._useRT) return;
        this._useRT = arg;
        this.getComponent(Camera).targetTexture = this._useRT ? this.deepSkyRT : null;
        this.skyBackRenderer.node.active = arg;
        if (arg) {
            this.skyBackRenderer.spriteFrame.texture = this.deepSkyRT;
            this.skyBackRenderer.spriteFrame.packable = false;
            this.skyBackRenderer.spriteFrame.flipUVY = !sys.isNative || (sys.os !== sys.OS.IOS && sys.os !== sys.OS.OSX);
        }
    }
    public get useRT(): boolean { return this._useRT; }

    @property private _useRT: boolean = false;

    protected onLoad(): void {
        this.useRT = false;
    }

    protected lateUpdate(dt: time.sec): void {
        const { pow10 } = cosmos;
        const { mainCamera: { node: viewer } } = core.getController(CosmosController);
        const { inType, centerName } = visit;
        const outer = interstellar.contains(inType) && !!centerName && centerName != 'Sun';
        this.node.setWorldPosition(
            outer ? viewer.worldPosition :
                pow10 <= STAY_VALVE ? Vec3.ZERO :
                    pow10 >= SYNC_VALVE ? viewer.worldPosition :
                        Vec3.multiplyScalar(v3a, viewer.worldPosition, (pow10 - STAY_VALVE) / SPAN)
        );
        // this.node.setWorldPosition(viewer.worldPosition);
        this.node.setWorldRotation(viewer.worldRotation);
        if (visit.inBlackhole && this.blackhole.node.active) {
            this.useRT = true;
            // console.log(smoothstep(-3, 0, this.blackhole.suggest - pow10) * EXAGGERATE_BOX);
            this.skybox.luminance = Math.max(1, smoothstep(-3, 0, this.blackhole.suggest - pow10) * EXAGGERATE_BOX);
            this.gravitational.photonColor.set(this.blackhole.diskColorStart);
            this.gravitational.photonColor.a = 255;
        } else {
            this.useRT = false;
            this.skybox.luminance = 1;
        }
    }

    protected start(): void {
    }
}

const STAY_VALVE: pow10 = 0;
const SYNC_VALVE: pow10 = 1;
const SPAN: pow10 = Math.abs(SYNC_VALVE - STAY_VALVE);
const v3a = new Vec3;
const EXAGGERATE_BOX = 10;